/* 
  ts 就是 js 的超集 是 js 的严格版本 让 js 步入编译语言的行列

  浏览器无法直接运行 .ts 文件 需要先编译成 es5语法的 .js  tsc demo.ts ==> demo.js

  js 对于数据类型没有限制 很随意，而 ts 对数据类型的限制非常严格
  
  它拥有很强大的错误检测机制 本身就是微软开发出来的语言 
  
  所以 vsCode 是它最好的编辑器 
*/

/* 
  基本数据类型：Number、String、Boolean、undefined、null、object、symbol、bigint
  这些类型和 js 一样
*/

// 不一样的数据类型

// 1 元组 是一种指定类型和长度的数组

let a: [string, number, number, object, boolean];
a = ["1", 2, 3, { x: 1 }, true]; // 长度和类型必须一一对应

// 2 枚举类型 {x,y,z} 转化为 ES5 实际上就是一个双向映射的对象
// 等价于 {'0':x, '1':y, '2':z, x:0, y:1, z:2}
// 枚举类型里的数据不能是对象类型 对象无法作为属性名(Map 除外)
// 最大的好处就是 名值对 的相互映射
enum color {
  r = 1,
  g,
  b,
} // 可以更改起始编号

console.log(color[1], color[2], color[3], color["r"], color["g"], color["b"]);

// 3 any 类型 不限定数据类型
// 一般用于预设一些未知数据类型的变量
let b: any = 1;
console.log(b, typeof b);
b = "你好";
console.log(b, typeof b);

// 用于取消函数返回值类型限制
function sayName(name: string): any {
  return name;
}
console.log(sayName("小明"));

// 4 void 类型 表示 空，不存在 只能给它赋值 undefined
let c: void = undefined;

// 5 never 类型 永远不存在或者不返回一个值 严格来说不算是数据类型
// 只是为了让 ts 严格，可用于异常处理
function foo(num: number): never {
  throw new Error("这程序无法终结，只能报错！");
}

// never 类型是所有类型的子类 因为它不存在 可以视为空的 所以可以赋值给任意类型
let str: string;
try {
  str = foo(1);
} catch (e) {
  console.log(e);
}
